# -*- coding: utf-8 -*-
# created on 2016/9/23


from mathsolver.functions.base import *
from sympy.abc import x, y, m, n
from mathsolver.functions.zhixian.property import GetFangXiang, GetZhiXianYiBanShi, GetZhiXianCoeff
from mathsolver.functions.root.jiefangchenzu import JieFangChenZu
from mathsolver.functions.zhixian.fangcheng import PointOnGraph
from mathsolver.functions.zhixian.base import zl_search_multiple


# 求点关于直线的对称点
class PointSymmetryLine(BaseFunction):
    """
    点(-5,1)关于直线x-2y+2=0的对称点是()
    """
    def solver(self, *args):
        point = args[0].sympify()
        eq = args[1].sympify()
        target_point = [m, n]
        self.steps.append(["", "设对称点坐标为 (%s,%s)" % (new_latex(target_point[0]), new_latex(target_point[1]))])
        yibanshi = GetZhiXianYiBanShi().solver(args[1]).output[0]
        coeff = GetZhiXianCoeff().solver(yibanshi).output[0]
        fangxiang_vector = GetFangXiang().solver(coeff).output[0].value['value']
        zhongdian = [(point[0] + target_point[0]) / 2, (point[1] + target_point[1]) / 2]
        target_vector = [target_point[0] - point[0], target_point[1] - point[1]]
        eq1 = [fangxiang_vector[0] * target_vector[0] + fangxiang_vector[1] * target_vector[1], S.Zero]
        zhixianfangcheng = (eq[0] - eq[1]).simplify()
        eq2 = [zhixianfangcheng.subs({x: zhongdian[0], y: zhongdian[1]}), S.Zero]
        self.steps.append(["则：", BaseEqs([eq1, eq2]).printing()])
        stepsolver = JieFangChenZu(verbose=True).solver(BaseEqs([eq1, eq2]), BaseVariables(target_point))
        solutions = stepsolver.output[0]
        self.steps.append(["", "解得: %s" % (solutions.printing())])
        m_answer = zl_search_multiple(solutions.sympify(), target_point[0])
        for ans in m_answer:
            val = target_point[0]
            val = val.subs(ans)
            val = val.expand().simplify()
            target_point[0] = val
        n_answer = zl_search_multiple(solutions.sympify(), target_point[1])
        for ans in n_answer:
            val = target_point[1]
            val = val.subs(ans)
            val = val.expand().simplify()
            target_point[1] = val
        self.steps.append(["", "所以，对称点坐标为(%s, %s)" % (new_latex(target_point[0]), new_latex(target_point[1]))])
        if len(args) == 3:
            name = args[2].value
            self.output.append(BasePoint({"name": name, "value": [target_point[0], target_point[1]]}))
        else:
            self.output.append(BasePoint({"name": "", "value": [target_point[0], target_point[1]]}))
        self.label.add("求点关于直线的对称点")
        return self


# 求点关于点的对称点
class PointSymmetryPoint(BaseFunction):
    """
    直线2x-y+3=0关于定点M(-1,2)对称的直线方程是()
    """
    def solver(self, *args):
        point1 = args[0].sympify()
        point2 = args[1].sympify()
        target_point = (m, n)
        self.steps.append(["", "设对称点为(%s, %s), 则" % (new_latex(target_point[0]), target_point[1])])
        eq1 = [(point1[0] + target_point[0]) / 2, point2[0]]
        eq2 = [(point1[1] + target_point[1]) / 2, point2[1]]
        self.steps.append(["", BaseEqs([eq1, eq2]).printing()])
        stepsolver = JieFangChenZu(verbose=True).solver(BaseEqs([eq1, eq2]), BaseVariables(target_point))
        jies = stepsolver.output[0].value
        jies_keys = list(jies.keys())
        self.steps.append(["解方程,得",
                           BaseEqs([[list(jies.keys())[0], jies[list(jies.keys())[0]].args[0]],
                                    [list(jies.keys())[1], jies[list(jies.keys())[1]].args[0]]]).printing()])
        if jies_keys[0] == target_point[0]:
            x_axis = jies[list(jies.keys())[0]].args[0]
            y_axis = jies[list(jies.keys())[1]].args[0]
        else:
            x_axis = jies[list(jies.keys())[1]].args[0]
            y_axis = jies[list(jies.keys())[0]].args[0]
        self.steps.append(["", "所以，对称点坐标为(%s, %s)" % (new_latex(x_axis), new_latex(y_axis))])
        self.output.append(BasePoint({"name": "", "value": [x_axis, y_axis]}))
        self.label.add("求点关于点的对称点")
        return self


# 求直线关于点的对称直线方程
class LineSymmetryPoint(BaseFunction):
    """
    直线x-2y+1=0关于直线x=1对称的直线方程是().
    """
    def solver(self, *args):
        target_point = args[1]
        if isinstance(args[1], str):
            text = args[1]
            if "原点" in text:
                target_point = BasePoint({"name": "", "value": [S.Zero, S.Zero]})
        self.steps.append(["", "在所求的直线上任意取一点A(%s,%s)" % (new_latex(x), new_latex(y))])
        stepsolver = PointSymmetryPoint().solver(BasePoint({"name": "", "value": [x, y]}), target_point)
        self.steps += stepsolver.steps
        stepsolver2 = PointOnGraph().solver(stepsolver.output[0], args[0])
        self.steps += stepsolver2.steps
        new_zhixian = stepsolver2.output[0].sympify()
        self.steps.append(["即", BaseZhiXian({"name": "", "value": [new_zhixian[0], new_zhixian[1]]}).printing()])
        self.output.append(BaseZhiXian({"name": "", "value": [new_zhixian[0], new_zhixian[1]]}))
        self.label.add("求直线关于点的对称直线方程")
        return self


# 求直线关于直线的对称直线方程
class LineSymmetryLine(BaseFunction):
    def solver(self, *args):
        graph = args[0].sympify()
        zhixian = args[1].sympify()
        self.steps.append(["", "在所求的直线上任意取一点A(%s,%s)" % (new_latex(x), new_latex(y))])
        stepsolver = PointSymmetryLine().solver(BasePoint({"name": "", "value": [x, y]}),
                                                BaseEq([zhixian[0], zhixian[1]]))
        self.steps += stepsolver.steps
        self.steps.append(["", "因为对称点在%s = %s上，代入得" % (new_latex(graph[0]), new_latex(graph[1]))])
        stepsolver1 = PointOnGraph().solver(stepsolver.output[0], args[0])
        target_zhixian = stepsolver1.output[0].value
        if len(args) == 3:
            if isinstance(args[2], BaseFuncName):
                # 设函数y=f(x)的图象与y=2^{x+a}的图象关于y=-x对称,f(-2)+f(-4)=1,则a=()
                f = solve(target_zhixian[0] - target_zhixian[1], y)[0]
                self.output.append(BaseFunc({"name": args[2].name, "type": "", "var": "x", "expression": f}))
        else:
            self.steps.append(["", BaseZhiXian({"name": "", "value": target_zhixian}).printing()])
            self.output.append(BaseZhiXian({"name": "", "value": target_zhixian}))
            self.label.add("求直线关于直线的对称直线方程")
        return self


if __name__ == '__main__':
    pass
